home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / V2 / DJLSR200.ZIP / src / libc / emu387 / npxsetup.c < prev   
Encoding:
C/C++ Source or Header  |  1996-01-14  |  3.3 KB  |  118 lines

  1. /* Copyright (C) 1994, 1995 Charles Sandmann (sandmann@clio.rice.edu)
  2.  * FPU setup and emulation hooks for DJGPP V2.0
  3.  * This file maybe freely distributed, no warranty. */
  4.  
  5. /* Note:  If this file is built with IMBED_EMU387 defined, the application 
  6.    should be linked with -lemu to imbed the code in the image.  This 
  7.    makes it easier to distribute an application with a single file.
  8.    The alternate behavior is to dynamically load the image. */
  9.  
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <io.h>
  14. #include <signal.h>
  15. #include <setjmp.h>
  16. #include <dpmi.h>
  17. #include <libc/internal.h>
  18. #include <sys/exceptn.h>
  19. #ifndef IMBED_EMU387
  20. #include <sys/dxe.h>
  21. static int (*_emu_entry)(jmp_buf exc);
  22. #else
  23. int _emu_entry(jmp_buf exc);
  24. #endif
  25.  
  26. /* crt0.o references __emu387_load_hook just to pull in this object in libemu.a.
  27.    Using -lemu -lc brings in the static objects instead of a dynamic link. */
  28.  
  29. int __emu387_load_hook;
  30.  
  31. /* The environment variable 387 can be used to disable a 387 which is present
  32.    (for testing) by setting it to "n".  The presence can be reported to 
  33.    stderr by setting 387 to "q" (query).  Unlike GO32, "y" is not supported
  34.    since it can hang the machine if a coprocessor is not really present.
  35.    If a 387 is not present under DPMI, we call a V1.0 DPMI extension to ask 
  36.    that Exception 7 be sent to our process.  If we don't have a 387, we 
  37.    attempt to load the EMU387.DXE and call it from the signal.
  38.  */
  39.  
  40. static void nofpsig(int sig)
  41. {
  42.   if(_emu_entry(__djgpp_exception_state))
  43.   {
  44.     raise(SIGFPE);
  45.     return;
  46.   }
  47.   longjmp(__djgpp_exception_state, __djgpp_exception_state->__eax);
  48. }
  49.  
  50. #ifdef RESTORE_FPU
  51. static void restore_DPMI_fpu_state(void)
  52. {
  53.   __dpmi_set_coprocessor_emulation(1);    /* Enable Coprocessor, no exceptions */
  54. }
  55. #endif
  56.  
  57. extern int _detect_80387(void);
  58.  
  59. void _npxsetup(char *argv0)
  60. {
  61.   char *cp;
  62.   char have_80387;
  63. #ifdef RESTORE_FPU
  64.   static int veryfirst = 1;
  65. #endif
  66.  
  67.   cp = getenv("387");
  68.   if (cp && (tolower(cp[0]) == 'n'))
  69.     have_80387 = 0;
  70.   else
  71.   {
  72.     /* This next function may fail, but that's OK.  This may fix the
  73.        nested FPU client fault - DJ */
  74.     __dpmi_set_coprocessor_emulation(1);
  75.     have_80387 = _detect_80387();
  76.   }
  77.  
  78.   if (cp && (tolower(cp[0]) == 'q')) {
  79.     if (!have_80387)
  80.       _write(2, "No ", 3);
  81.     _write(2, "80387 detected.\r\n", 17);
  82.   }
  83.  
  84.   if(!have_80387) {
  85.     /* Flags value 3 means coprocessor emulation, exceptions to us */
  86.     if (__dpmi_set_coprocessor_emulation(3)) {
  87.       _write(2, "Warning: Coprocessor not present and DPMI setup failed!\r\n", 57);
  88.       _write(2, "         If application attempts floating operations system may hang!\r\n", 71);
  89.     } else {
  90. #ifndef IMBED_EMU387
  91.       char emuname[512];
  92.       cp = getenv("EMU387");
  93.       if (!cp) {
  94.         char *last, c;
  95.         cp = last = emuname;
  96.         while((c = *cp++ = *argv0++))
  97.           if(c == '/' || c == '\\')
  98.             last = cp;
  99.         *last = 0;
  100.         strcat(emuname,"emu387.dxe");
  101.         cp = emuname;
  102.       }
  103.       _emu_entry = _dxe_load(cp);
  104.       if (_emu_entry == 0)
  105.         return;
  106. #endif
  107. #ifdef RESTORE_FPU
  108.       if (veryfirst)
  109.     {
  110.       veryfirst = 0;
  111.       atexit(restore_DPMI_fpu_state);
  112.     }
  113. #endif
  114.       signal(SIGNOFP, nofpsig);
  115.     }
  116.   }
  117. }
  118.